<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
                      "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>MWRover</title>
    <meta name="viewport" content="width=device-width, user-scalable=no"/>
    <style type="text/css" charset="utf-8">
      body {
        margin: 0pt;
        background-color: #000033;
        overflow: hidden;
        font-size: 8pt;
        font-family: Arial, Verdana, Helvetica, sans-serif;
        border: none;
        border-style: none;
        color: #FFFFFF;
        font-size: 12pt;
        text-align: center;
      }
      button, input, textarea, select, option {
        color: #FFFFFF;
        font-size: 12pt;
        font-family: Arial, Verdana, Helvetica, sans-serif;
        border: solid #003399 1px;
        background-color: #000440;
        overflow: hidden;
      }
      button {
        width: 40%;
        height: 50px;
      }
    </style>
    <script type="text/javascript" charset="utf-8" src="phonegap.js"/>
    <script type="text/javascript" charset="utf-8">
    
    //Mapping Table for Wheel Motion Directions 
    var F   = [1,1,-1,-1];
    var R   = [-1,1,1,-1];
    var CW  = [-1,-1,-1,-1];
    
    var accelID = null;
    var compassID = null;
    var servoPositions = [0,0,0,0];
    var servoPositionCentre = [1500,1500,1500,1500];
    var lastCommandTime = 0;
    
    var servoCentre = 1500;
    var servoRange = 500;
    var servoRangeMin = servoCentre-servoRange;
    var servoRangeMax = servoCentre+servoRange;

    var AccelX = 0;
    var AccelY = 0;
    var AccelZ = 0;
    var AccelXOrigin = 0;
    var AccelYOrigin = 0;
    var AccelZOrigin = 0;
    var CompassHeading = 0;
    var CompassHeadingOrigin = 0;
    
    var bEnabled = false;
    var bRotate = false;
    var bFlipDir = true;  //True for default accelerometer
    
    commandURL = "http://10.10.10.10:8080/command/";
    
    // Wait for PhoneGap to load
    function onLoad(){
      document.addEventListener("deviceready", onDeviceReady, false);
      
      move   = document.getElementById("move");
      rotate = document.getElementById("rotate");
      
      move.onmousedown = move.ontouchstart = startMove;
      rotate.onmousedown = rotate.ontouchstart = startRotate;
      
      document.onmouseup = document.ontouchend = stop;      
    }

    // PhoneGap is ready
    function onDeviceReady(){
      startWatch();
      document.getElementById("start").disabled = false;
      document.getElementById("stop").disabled = true;
    }
    
    // Start watching the acceleration
    function startWatch(){
        var options = { frequency: 250 }; //Update Interval
        accelID = navigator.accelerometer.watchAcceleration(onSuccessAccel, onError, options);
        compassID = navigator.compass.watchHeading(onSuccessCompass, onError, options);
    }

    // Stop watching the acceleration
    function stopWatch(){
        if (accelID) {
        	navigator.accelerometer.clearWatch(accelID);
        	accelID = null;
        }
        if (compassID){
            navigator.compass.clearWatch(compassID);           
            compassID = null;
        }
    }
    
    // onSuccessAccel: Get a snapshot of the current acceleration
    function onSuccessAccel(acceleration){
        var element = document.getElementById('accelerometer');
        element.innerHTML = 'Acceleration X: ' + acceleration.x + '<br />' +
                            'Acceleration Y: ' + acceleration.y + '<br />' +
                            'Acceleration Z: ' + acceleration.z + '<br />' +
                            'Timestamp: '      + acceleration.timestamp + '<br />';
        AccelX = acceleration.x;
        AccelY = acceleration.y;
        AccelZ = acceleration.z;
        
        accelMove();
    }
    
    // onSuccessCompass: Get a snapshot of the current compass heading
    function onSuccessCompass(heading){
        var element = document.getElementById('heading');
        element.innerHTML = 'Heading: ' + heading;
        CompassHeading = heading;
    }
    
    // onError: Failed to get the acceleration/heading
    function onError(){
        stopWatch();
    }
    
    function accelMove(){
      //This is really accel/compass change... but I'm too lazy to rename
      if(!bEnabled){
        return;
      }

      //Calculate difference to start position      
      if(bRotate){
        var headingChange = 0;
        headingChange = CompassHeading - CompassHeadingOrigin;
        if(headingChange<-180){headingChange+=360;}
        if(headingChange>180){headingChange-=360;}
        servoX = servoRange * (headingChange)/30;
      } else {
        servoX = servoRange * (AccelX - AccelXOrigin)/5;
        servoY = servoRange * (AccelY - AccelYOrigin)/5;
        if(bFlipDir){
          servoX = servoX * -1;
        }
      }
      
      date = new Date();
      currentTime = date.getTime();
      
      //Limit command rate to 4Hz to avoid spamming the controller
      if(currentTime-lastCommandTime > 250){
        for(x in servoPositions){
          if(bRotate){
            servoPositions[x] = Math.round((CW[x] * servoX + servoCentre)*100)/100;
            servoPositions[x] = ((servoPositions[x] < servoRangeMin) ? servoRangeMin : ((servoPositions[x] > servoRangeMax) ? servoRangeMax : servoPositions[x]));
            document.getElementById("debug").innerHTML = "Rotating " + servoPositions;
          } else {
            servoPositions[x] = Math.round((-F[x] * servoY + -R[x] * servoX + servoCentre)*100)/100;
            servoPositions[x] = ((servoPositions[x] < servoRangeMin) ? servoRangeMin : ((servoPositions[x] > servoRangeMax) ? servoRangeMax : servoPositions[x]));
            document.getElementById("debug").innerHTML = "Moving " + servoPositions;
          }
        }
        lastCommandTime = currentTime;
        sendCommand(servoPositions);
      }

      return false;
    }    


    var commandSend = new XMLHttpRequest();
    
    function sendCommand(commandPositions){
      var PostString = "";
      //Get all input fields
      for(x in commandPositions){
        if(PostString != ""){
          PostString += "&";
        }
        PostString = PostString += x + "=" + commandPositions[x];
      }
      //Send the request
      
      commandSend.open('POST', commandURL, false);
      commandSend.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      commandSend.send(PostString);  
    }
    
    function setURL(){
      commandURL = document.getElementById('serverurl').value;
    }
    
    function setZeroPoint(){
      AccelXOrigin = AccelX;
      AccelYOrigin = AccelY;
      AccelZOrigin = AccelZ;
      CompassHeadingOrigin = CompassHeading;
    }
    
    function startMove(){
      //Zero on start
      setZeroPoint();
      bEnabled = true;
      bRotate = false;
    }
    
    function startRotate(){
      //Zero on start
      setZeroPoint();
      bEnabled = true;
      bRotate = true;      
    }
    
    function stop(){
      bEnabled = false;
      //Send stop command too
      sendCommand(servoPositionCentre);
      document.getElementById("debug").innerHTML = "STOPPED";
    }
    
    function flipDir(){
      if(bFlipDir){
        bFlipDir = false;
        document.getElementById("direction").innerHTML = "Direction : Normal";
      } else {
        bFlipDir = true;
        document.getElementById("direction").innerHTML = "Direction : Bruce Special";
      }
    }
    
    </script>
  </head>
  <body onload="onLoad()">
    <h1>MWRover Test</h1>
    <div id="accelerometer">Waiting for accelerometer...</div>
    <div id="heading">Waiting for Compass...</div>
    <br>
    <div id="direction">Direction : Normal</div>
    <div id="debug">Debug Line</div>
    <br>
    <input  id="commandurl" type="text" size="30" value="http://10.10.10.10:8080/command/"/>
    <br>
    <button id="seturl" onclick="setURL();">Set URL</button>
    <br>
    <br>
    <button id="flipdir" onclick="flipDir();">Flip Left/Right</button>
    <br>
    <br>
    <button id="move">Move</button>
    <button id="rotate">Rotate</button>
  </body>
</html>
